<?php

declare(strict_types=1);

namespace App\Traits\Model\Admin;

use Donjan\Casbin\Enforcer;
use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Events\Deleted;
use App\Scopes\Admin\Role as RoleScope;

trait Role
{
    /**
     * The "booting" method of the model.
     */
    protected function boot():void
    {
        parent::boot();
        static::addGlobalScope(new RoleScope);
    }

    /**
     * 设置应用
     */
    public function setAppAttribute()
    {
        $app = getApp();

        $this->attributes['app'] = $app;
        if ($app === 'shop') {
            $this->attributes['app_id'] = getInfo($app, 'shop_id');
        }
    }

    /**
     * 编辑权限
     * @param Collection $permissionIds
     * @return void
     */
    public function updatePermission(Collection $permissions)
    {
        $app = getApp();

        $permissionEnforcers = Enforcer::getPermissionsForUserInDomain((string)$this->id, $app);

        foreach ($permissionEnforcers as $permissionEnforcer) { // 当前角色不在角色列表中则删除
            if (!in_array(['path' => $permissionEnforcer[2], 'method' => $permissionEnforcer[3]], $permissions->toArray())) {
                Enforcer::deletePermissionForUser((string)$this->id, $app, $permissionEnforcer[2], $permissionEnforcer[3]);
            }
        }

        $this->addPermission($permissions);
    }

    /**
     * 添加权限
     * @param Collection $permissionIds
     * @return void
     */
    public function addPermission(Collection $permissions)
    {
        $app = getApp();

        foreach ($permissions as $permission) {
            Enforcer::addPermissionForUser((string)$this->id, $app, $permission->path, $permission->method);
        }
    }

    /**
     * 删除事件
     * @param Deleted $deleted
     * @return void
     */
    public function deleted(Deleted $deleted)
    {
        $app = getApp();

        $permissions = Enforcer::getPermissionsForUserInDomain((string)$this->id, $app);
        foreach ($permissions as $permission) {
            Enforcer::deletePermissionForUser((string)$this->id, $app, $permission[2], $permission[3]);
        }
    }
}
